require_dependency "search"
class Photo < ActiveRecord::Base
  require                     'RMagick'
  include                     Magick
  
  has_many                    :comments
  has_many                    :partnerships
  has_many                    :items
  has_many                    :orders,          :through => :items
  has_many                    :galleries,       :through => :partnerships
  has_many                    :approvals
  has_attachment              :storage =>       :file_system, 
                              :processor=>      :rmagick,
                              :content_type =>  :image,
                              :max_size =>      6000.kilobytes,
                              :thumbnails => {  :tiny =>  '75x75',
                                                :thumb => '100x100',
                                                :small => '200x150',
                                                :medium => '320x240',
                                                :screen => '800x600' }
  validates_as_attachment
  searches_on                 :caption,
                              :location,
                              :city,
                              :state,
                              :country,
                              :author,
                              :keywords
  
  before_save                 :assign_metadata
  after_save                  :create_partnerships
  after_destroy               :destroy_dependents
  
  def is_purchasable?
    !self.non_purchasable?
  end
  
  def in_more_than_one_gallery?
    self.galleries.length > 1
  end
  
  def sanitized_caption
    self.caption ? (self.caption.gsub(/\\|'/) {|c| "\\#{c}"}.gsub("\r","").gsub("\n","")) : ""
  end
  
  def is_invisible?
    !self.galleries.detect{|gallery| gallery.invisible?}.nil?
  end
  
  def metadata_exists?
    self.camera_model? or self.caption? or self.location or self.camera_make
  end
  
  def assign_metadata
    unless self.metadata_exists?
      #raise self.temp_path
      photo                     = Magick::Image.read(self.temp_path).first
      self.caption              = photo.get_iptc_dataset(Magick::IPTC::Application::Caption).to_s.toutf8
      self.location             = photo.get_iptc_dataset(Magick::IPTC::Application::Sub_Location).to_s.toutf8
      self.city                 = photo.get_iptc_dataset(Magick::IPTC::Application::City).to_s.toutf8
      self.state                = photo.get_iptc_dataset(Magick::IPTC::Application::State).to_s.toutf8
      self.country              = photo.get_iptc_dataset(Magick::IPTC::Application::Country_Primary_Location_Name).to_s.toutf8
      self.author               = photo.get_iptc_dataset(Magick::IPTC::Application::Author).to_s.toutf8
      self.keywords             = photo.get_iptc_dataset(Magick::IPTC::Application::Keywords).to_s.toutf8
      self.lens                 = photo.properties.fetch("aux:Lens", "").to_s.toutf8
      self.camera_serial_number = photo.properties.fetch("aux:SerialNumber", "").to_s.toutf8
      self.camera_make          = photo.properties.fetch("tiff:Make", "").to_s.toutf8
      self.camera_model         = photo.properties.fetch("tiff:Model", "").to_s.toutf8
      self.exposure_time        = photo.properties.fetch("exif:ExposureTime", "").to_s.toutf8
      self.fstop                = photo.properties.fetch("exif:FNumber", "").to_s.toutf8
      self.shutter_speed        = photo.properties.fetch("exif:ShutterSpeedValue", "").to_s.toutf8
      self.focal_length         = photo.properties.fetch("exif:FocalLength", "").to_s.toutf8
      self.iso_rating           = Hash[*photo.get_exif_by_entry().flatten].fetch("ISOSpeedRatings", "").to_s.toutf8
      self.date_time            = photo.properties.fetch("exif:DateTimeOriginal", "").to_s.toutf8
    end
  end
  
  def approval_for(gallery, current_user)
    Approval.find(:all, :conditions => ["photo_id = #{self.id} AND gallery_id = #{gallery.id} AND user_id = #{current_user.id} AND approved = ?", true]).first
  end
  
  def approval_in(gallery)
    Approval.find(:all, :conditions => ["photo_id = #{self.id} AND gallery_id = #{gallery.id}"]).first
  end
  
  def approved_in?(gallery)
    Approval.find(:all, :conditions => ["photo_id = #{self.id} AND gallery_id = #{gallery.id} AND approved = ?", true]).first ? true : false
  end
  
  def declined_in?(gallery)
    Approval.find(:all, :conditions => ["photo_id = #{self.id} AND gallery_id = #{gallery.id} AND declined = ?", true]).first ? true : false
  end
  
  def approval_status(gallery, current_user)
    approval = Approval.find(:all, :conditions => ["photo_id = #{self.id} AND gallery_id = #{gallery.id} AND user_id = #{current_user.id} AND declined = ?", true]).first
    "approved" if approval.approved?
    "declined" if approval.declined?
  end
  
  def needs_review_in?(gallery)
    return true if self.approvals.empty?
    self.approvals.each {|approval| !gallery.approvals.include?(approval) ? (return true) : (return false)}
  end
  
  def users
    self.galleries.empty? ? [] : ((users = self.galleries.collect {|gallery| gallery.users unless gallery.users.empty?}.reject {|item| item.nil?}.flatten) ? users : [])
  end
  
  def gallery_ids=(gallery_ids = [])
    @gallery_ids = gallery_ids
  end

protected
  def create_partnerships
    self.partnerships.each {|partnership| partnership.destroy if partnership.gallery and @gallery_ids} if self.partnerships
    @gallery_ids.each {|gallery_id| Partnership.create!(:photo_id => self.id, :gallery_id => gallery_id)} unless @gallery_ids.nil?
  end
  
  def destroy_dependents
    self.comments.each {|comment| comment.destroy} unless self.comments.empty?
    self.partnerships.each {|partnership| partnership.destroy} unless self.partnerships.empty?
    self.approvals.each {|approval| approval.destroy} unless self.approvals.empty?
    self.items.each {|item| item.destroy} unless self.items.empty?
  end
end
